package rexsee.core.browser.clazz;

import rexsee.core.browser.Browser;
import rexsee.core.browser.RexseePrompt;
import rexsee.core.browser.clazz.ActivityResult.ActivityResultListener;
import rexsee.core.lang.RexseeLanguage;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.net.Uri;
import android.os.Message;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.JsPromptResult;
import android.webkit.JsResult;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebStorage;
import android.webkit.WebView;
import android.widget.FrameLayout;
import android.widget.ProgressBar;
import android.widget.Toast;

public class BrowserChromeClient extends WebChromeClient {

	private final Browser mBrowser;
	private final Context mContext;

	public BrowserChromeClient(Browser browser) {
		mBrowser = browser;
		mContext = browser.getContext();
	}
	@Override
	public void onReceivedTitle(WebView view, String title) {
		mBrowser.history.setCurrentTitle(title);
		mBrowser.titleListeners.run(mContext, (Browser) view, title);
	}
	@Override
	public void onProgressChanged(WebView view, int newProgress) {
		mBrowser.progressListeners.run(mContext, (Browser) view, newProgress);
	}
	@Override
	public boolean onJsTimeout() {
		mBrowser.application.alert("Javascript", "Timeout.");
		if (mBrowser.logListeners != null) mBrowser.logListeners.run(mContext, mBrowser, LogListeners.LOG_TYPE_ERROR, "Javascript Timeout.");
		return true;
	}
	@Override
	public void onConsoleMessage(String message, int lineNumber, String sourceID) {
		String fileError = "Not allowed to load local resource: ";
		if (message.startsWith(fileError)) {
			mBrowser.function.load(message.replace(fileError, ""));
		} else {
			if (mBrowser.allowErrorDialog) {
				if (!mBrowser.application.resources.prefix.equals("rexsee")) {
					message = message.replace("rexsee", mBrowser.application.resources.prefix);
					message = message.replace("Rexsee", mBrowser.application.resources.prefix.substring(0, 1).toUpperCase() + mBrowser.application.resources.prefix.substring(1));
				}
				mBrowser.application.alert("Javascript", message + "<br>Line: " + lineNumber + "<br>URL: " + sourceID);
			}
		}
		if (mBrowser.logListeners != null) mBrowser.logListeners.run(mContext, mBrowser, LogListeners.LOG_TYPE_ERROR, "Line " + lineNumber + " of " + sourceID + ":" + message);
	}
	@Override
	public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
		AlertDialog dialog = new AlertDialog.Builder(mContext).create();
		dialog.setIcon(mBrowser.application.icon);
		dialog.setTitle(RexseeLanguage.TITLE_ALERT);
		dialog.setMessage(message);
		dialog.setCancelable(false);
		dialog.setOnKeyListener(new Dialog.OnKeyListener() {
			@Override
			public boolean onKey(DialogInterface arg0, int arg1, KeyEvent arg2) {
				if (arg1 == KeyEvent.KEYCODE_SEARCH) return true;
				else return false;
			}
		});
		dialog.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int whichButton) {
				dialog.dismiss();
				result.confirm();
			}
		});
		dialog.show();
		return true;
	}
	@Override
	public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
		AlertDialog dialog = new AlertDialog.Builder(mContext).create();
		dialog.setIcon(mBrowser.application.icon);
		dialog.setTitle(RexseeLanguage.TITLE_CONFIRM);
		dialog.setMessage(message);
		dialog.setCancelable(false);
		dialog.setOnKeyListener(new Dialog.OnKeyListener() {
			@Override
			public boolean onKey(DialogInterface arg0, int arg1, KeyEvent arg2) {
				if (arg1 == KeyEvent.KEYCODE_SEARCH) return true;
				else return false;
			}
		});
		dialog.setButton(DialogInterface.BUTTON_NEGATIVE, mContext.getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int whichButton) {
				dialog.dismiss();
				result.confirm();
			}
		});
		dialog.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getResources().getString(android.R.string.cancel), new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int whichButton) {
				dialog.dismiss();
				result.cancel();
			}
		});
		dialog.show();
		return true;
	}
	@Override
	public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, final JsPromptResult result) {
		mBrowser.promptListeners.run(message, defaultValue, new RexseePrompt.OnPromptReturnListener() {
			@Override
			public void run(String rtn) {
				mBrowser.promptListeners.canceled = (rtn == null) ? true : false;
				result.confirm((rtn == null) ? "" : rtn);
			}
		});
		return true;
	}
	@Override
	public void onExceededDatabaseQuota(String url, String databaseIdentifier, long currentQuota, long estimatedSize, long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
		quotaUpdater.updateQuota(10 * 1024 * 1024);
		if (mBrowser.logListeners != null) mBrowser.logListeners.run(mContext, mBrowser, LogListeners.LOG_TYPE_MESSAGE, "Exceeded database quota:" + totalUsedQuota + "/" + currentQuota);
	}
	@Override
	public void onReachedMaxAppCacheSize(long spaceNeeded, long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
		quotaUpdater.updateQuota(spaceNeeded * 2);
		if (mBrowser.logListeners != null) mBrowser.logListeners.run(mContext, mBrowser, LogListeners.LOG_TYPE_MESSAGE, "Reached maximum appllication cache size:" + totalUsedQuota + "/" + spaceNeeded);
	}
	@Override
	public void onCloseWindow(WebView window) {
		try {
			if (mBrowser.windowListener != null) mBrowser.windowListener.closeWindow((Browser) window);
		} catch (Exception e) {
			mBrowser.exception("onCloseWindow", e);
		}
	}
	@Override
	public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
		try {
			if (mBrowser.windowListener != null) {
				Browser newBrowser = mBrowser.windowListener.getNewBrowser(mBrowser, isDialog, isUserGesture, false);
				if (newBrowser != null) {
					WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
					transport.setWebView(newBrowser);
					resultMsg.sendToTarget();
					return true;
				} else {
					return false;
				}
			} else {
				return false;
			}
		} catch (Exception e) {
			mBrowser.exception("onCreateWindow", e);
			return false;
		}
	}

	//About video tag in HTML5
	@Override
	public void onHideCustomView() {
		super.onHideCustomView();
		try {
			FrameLayout cover = mBrowser.containerDiv.coverLayout;
			if (cover.getChildCount() > 0) {
				Object tag = cover.getTag();
				if (tag != null && tag instanceof Runnable) {
					cover.removeAllViews();
					((Runnable) tag).run();
					cover.setTag(null);
					cover.setBackgroundColor(Color.TRANSPARENT);
					cover.setVisibility(View.GONE);
				}
			}
		} catch (Exception e) {
			Toast.makeText(mContext, "Exception:" + e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
		}
	}
	@Override
	public void onShowCustomView(View view, final CustomViewCallback callback) {
		super.onShowCustomView(view, callback);
		if (view == null) return;
		onHideCustomView();
		try {
			FrameLayout cover = mBrowser.containerDiv.coverLayout;
			cover.setBackgroundColor(Color.parseColor("#EE000000"));
			cover.addView(view);
			cover.setVisibility(View.VISIBLE);
			cover.setTag(new Runnable() {
				@Override
				public void run() {
					if (callback != null) callback.onCustomViewHidden();
				}
			});
		} catch (Exception e) {
			Toast.makeText(mContext, "Exception:" + e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
		}
	}
	@Override
	public Bitmap getDefaultVideoPoster() {
		return BitmapFactory.decodeResource(mContext.getResources(), android.R.drawable.ic_menu_camera);
	}
	@Override
	public View getVideoLoadingProgressView() {
		return new ProgressBar(mContext);
	}

	// For Android > 3.0
	public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
		mBrowser.mUploadMessage = uploadMsg;
		Intent i = new Intent(Intent.ACTION_GET_CONTENT);
		i.addCategory(Intent.CATEGORY_OPENABLE);
		i.setType("*/*");
		mBrowser.activityResult.start(Intent.createChooser(i, ""), new ActivityResultListener() {
			@Override
			public void run(int resultCode, Intent resultIntent) {
				if (mBrowser.mUploadMessage != null) {
					Uri result = (resultIntent == null || resultCode != Activity.RESULT_OK) ? null : resultIntent.getData();
					mBrowser.mUploadMessage.onReceiveValue(result);
					mBrowser.mUploadMessage = null;
				}
			}
		});
	}

	// For Android < 3.0
	public void openFileChooser(ValueCallback<Uri> uploadMsg) {
		openFileChooser(uploadMsg, "");
	}

}
